import pandas as pd
import os
from typing import Optional
from src.file.utils import get_file_path


def read_excel_file(filename: str) -> Optional[pd.DataFrame]:
    """读取Excel文件"""
    try:
        file_path = get_file_path(filename)
        # 默认读取第一个sheet
        df = pd.read_excel(file_path, header=None)
        return df
    except FileNotFoundError:
        print(f"错误: 找不到文件 {filename}")
        return None
    except Exception as e:
        print(f"读取文件 {filename} 时出错: {e}")
        return None


# FIXME：目前的逻辑是：从第二行开始，检查每一列的数据，如果包含"教师"，则认为该列是教师列，并返回行数 - 4 = 班级数
# FIXME：目前逻辑问题：实际班级信息在第一列，并没有直接从第一列判断班级数量
def get_class_count(data: pd.DataFrame) -> Optional[int]:
    """从已读取的数据中统计班级数量"""
    try:
        if data is None:
            return None

        # 检查数据是否为空
        if data.empty:
            print("错误: Excel文件为空")
            return None

        # 获取第二列数据（索引为1）
        if len(data.columns) < 2:
            print("错误: Excel文件列数少于2列")
            return None

        second_column = data.iloc[:, 1]  # 第二列数据

        # 查找第一个内容为"教师"的行，行数-4 就是班级数
        for index, value in second_column.items():
            if isinstance(value, str) and value.strip() == "教师":
                # 确保索引为整数类型后返回行号 - 4 = 班级数
                if isinstance(index, int):
                    return index - 4
                else:
                    print("错误: 行索引不是整数类型")
                    return None

        print("未找到内容为'教师'的行")
        return None

    except Exception as e:
        print(f"查找教师行时出错: {e}")
        return None


def _find_subject_in_cell(cell_value: str, subjects: list[str]) -> Optional[str]:
    """在单元格中查找科目"""
    if isinstance(cell_value, str):
        stripped_value = cell_value.strip()
        for subject in subjects:
            if subject in stripped_value:
                return subject
    return None


def _is_subject_already_recorded(subject: str, found_subjects: list[dict]) -> bool:
    """检查科目是否已经记录"""
    return any(item['subject'] == subject for item in found_subjects)


def _order_subjects_by_config(found_subjects: list[dict], config_subjects: list[str]) -> list[dict]:
    """按配置文件中的顺序排列科目"""
    ordered_subjects = []
    for subject in config_subjects:
        for item in found_subjects:
            if item['subject'] == subject:
                ordered_subjects.append(item)
                break
    return ordered_subjects


def get_subjects_info(data: pd.DataFrame) -> Optional[list[dict]]:
    """从Excel数据中提取考试科目名称列表及其位置信息，按配置文件中的顺序排列"""
    try:
        # 数据有效性检查
        if data is None or data.empty:
            print("错误: Excel文件为空")
            return None

        # 导入配置
        from config.config import SUBJECTS, EXCEL_SETTINGS
        column_check_positions = EXCEL_SETTINGS['COLUMN_CHECK_POSITIONS']
        max_rows_to_check = EXCEL_SETTINGS['MAX_ROWS_TO_CHECK']
        
        # 检查配置中的列位置是否超出数据范围
        if data.columns.size > 0 and max(column_check_positions) >= len(data.columns):
            print(f"错误: 配置的列位置超出数据范围，数据列数: {len(data.columns)}，配置最大列位置: {max(column_check_positions)}")
            return None

        # 使用列表存储找到的科目及其位置信息
        found_subjects = []

        # 遍历指定的列位置
        for col_index in column_check_positions:
            # 查找指定列中的科目
            column_subjects = _find_subjects_in_column(data, col_index, max_rows_to_check, SUBJECTS)
            # 将找到的科目添加到结果列表中
            for subject_info in column_subjects:
                if not _is_subject_already_recorded(subject_info['subject'], found_subjects):
                    found_subjects.append(subject_info)
                else:
                    # 发现重复科目，提示用户检查原始表格
                    print(f"警告: 在表格中发现重复科目 '{subject_info['subject']}'，请检查原始表格数据是否正确")
                    return None

        # 按 SUBJECTS 中的顺序重新排列
        ordered_subjects = _order_subjects_by_config(found_subjects, SUBJECTS)
        
        return ordered_subjects if ordered_subjects else None

    except Exception as e:
        print(f"统计考试科目数量时出错: {e}")
        return None


def _find_subjects_in_column(data: pd.DataFrame, col_index: int, max_rows_to_check: int, 
                            subjects: list[str]) -> list[dict]:
    """在指定列中查找科目"""
    # 限制检查行数，避免处理过大的数据
    max_rows = min(len(data), max_rows_to_check)
    column_data = data.iloc[:max_rows, col_index]
    found_subjects = []

    # 检查该列中的每行数据
    for row_index, cell_value in enumerate(column_data):
        subject = _find_subject_in_cell(cell_value, subjects)
        if subject:
            # 对于字符串类型，存储去除空白后的值；对于非字符串类型，转换为字符串存储
            cell_value_to_store = cell_value.strip() if isinstance(cell_value, str) else str(cell_value)
            found_subjects.append({
                'subject': subject,
                'row': row_index,
                'col': col_index,
                'value': cell_value_to_store
            })
    
    return found_subjects
